package com.echo.distributedlock.config;

import com.echo.distributedlock.aspect.DistributedLockAspect;
import com.echo.distributedlock.enmus.ModeEnum;
import com.echo.distributedlock.service.LockService;
import com.echo.distributedlock.service.impl.DbLockServiceImpl;
import com.echo.distributedlock.service.impl.RedissonLockServiceImpl;
import com.echo.distributedlock.service.impl.ZooKeeperLockServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * @author lmy
 */
@Configuration
public class LockConfig {

    private static final Map<ModeEnum, Supplier<LockService>> MODE_MAP = new HashMap<>(3);
    {
        MODE_MAP.put(ModeEnum.DB, this::getDbLockService);
        MODE_MAP.put(ModeEnum.REDISSON, this::getRedissonLockService);
        MODE_MAP.put(ModeEnum.ZOOKEEPER, this::getZooKeeperLockService);
    }

    @Resource
    private LockProperties lockProperties;

    @Bean
    public LockService getLockService() {
        if (Objects.nonNull(lockProperties.getMode())) {
            ModeEnum modeEnum = ModeEnum.chooseMode(lockProperties.getMode());
            Supplier<LockService> supplier = MODE_MAP.get(modeEnum);
            return supplier.get();
        }
        return null;
    }

    @Bean
    public DistributedLockAspect initAspect() {
        return new DistributedLockAspect();
    }

    private LockService getDbLockService() {
        return new DbLockServiceImpl();
    }

    private LockService getRedissonLockService() {
        return new RedissonLockServiceImpl();
    }

    private LockService getZooKeeperLockService() {
        return new ZooKeeperLockServiceImpl();
    }
}
